/**
 * 图片处理中间件
 * 处理带有特定参数的图片请求，生成缩略图并缓存
 */
import fs from 'fs-extra';
import path from 'path';
import sharp from 'sharp';
import { getProjectRoot } from '../utils/index.js';
import config from '../../config.js';

/**
 * 解析图片处理参数
 * @param {string} queryString - 查询字符串
 * @returns {Object|null} - 解析后的参数对象，如果不是有效的处理参数则返回null
 */
const parseImageParams = (queryString) => {
    if (!queryString || !queryString.includes('imageMogr2/thumbnail')) {
        return null;
    }

    const match = queryString.match(/thumbnail\/(\d+)x(\d+)>/);
    if (!match) {
        return null;
    }

    return {
        width: parseInt(match[1], 10),
        height: parseInt(match[2], 10),
        ignoreError: queryString.includes('ignore-error/1')
    };
};

/**
 * 生成缓存文件路径
 * @param {string} originalPath - 原始文件路径
 * @param {Object} params - 处理参数
 * @returns {string} - 缓存文件路径
 */
const getCachePath = (originalPath, params) => {
    const { width, height } = params;
    const projectRoot = getProjectRoot();
    const uploadPath = path.join(projectRoot, config.uploadPath);
    
    // 获取相对于 public/src 的路径
    const relativePath = path.relative(uploadPath, originalPath);
    const dirPath = path.dirname(relativePath);
    
    // 获取文件名和扩展名
    const filename = path.basename(originalPath);
    const ext = path.extname(filename);
    const name = path.basename(filename, ext);
    
    // 创建一个唯一的缓存文件名
    const cacheFilename = `${name}_${width}x${height}${ext}`;
    
    // 确保缓存目录存在
    const cacheDirPath = path.join(projectRoot, 'public', 'cache', dirPath);
    fs.ensureDirSync(cacheDirPath);
    
    return path.join(cacheDirPath, cacheFilename);
};

/**
 * 处理图片并生成缩略图
 * @param {string} originalPath - 原始文件路径
 * @param {string} cachePath - 缓存文件路径
 * @param {Object} params - 处理参数
 * @returns {Promise<boolean>} - 处理是否成功
 */
const processImage = async (originalPath, cachePath, params) => {
    try {
        const { width, height } = params;
        
        await sharp(originalPath)
            .resize({
                width,
                height,
                fit: 'inside',
                withoutEnlargement: true
            })
            .toFile(cachePath);
        
        return true;
    } catch (error) {
        console.error('Process image error:', error);
        return false;
    }
};

/**
 * 图片处理中间件
 */
export const imageProcessor = async (req, res, next) => {
    // 只处理 /src 路径下的请求
    if (!req.path.startsWith('/')) {
        return next();
    }
    
    // 解析查询参数
    const queryString = req.url.split('?')[1];
    const params = parseImageParams(queryString ? decodeURIComponent(queryString) : '');
    if (!params) {
        return next();
    }
    
    // 获取原始文件路径
    const projectRoot = getProjectRoot();
    const originalPath = path.join(projectRoot, config.uploadPath, req.path);
    
    // 检查原始文件是否存在
    if (!await fs.pathExists(originalPath)) {
        if (params.ignoreError) {
            return next();
        }
        return res.status(404).send('Not Found');
    }
    
    // 获取缓存文件路径
    const cachePath = getCachePath(originalPath, params);
    
    // 检查缓存是否存在
    if (await fs.pathExists(cachePath)) {
        // 设置缓存有效期
        res.setHeader('Cache-Control', config.cache.control);
        return res.sendFile(cachePath);
    }
    
    // 处理图片并生成缩略图
    const success = await processImage(originalPath, cachePath, params);
    
    if (success) {
        // 设置缓存有效期
        res.setHeader('Cache-Control', config.cache.control);
        return res.sendFile(cachePath);
    } else if (params.ignoreError) {
        return next();
    } else {
        return res.status(500).send('Internal Server Error');
    }
};

export default imageProcessor;